#include<stdio.h>
//int main() 
//{
//    int a[5] = { 1, 2, 3, 4, 5 };
//    int* ptr = (int*)(&a + 1);
//    printf("%d,%d", *(a + 1), *(ptr - 1));
//    return 0;
//}


//
//int main()
//{
//    char ch[3][5] = { "AAAA","BBB","CC" };
//    printf("\"%s\"\n", ch[1]);
//    return 0;
//}



//
//int ra[100000];
//
//int* productExceptSelf(int* nums, int numsSize, int* returnSize) 
//{
//    for (int i = 0; i < numsSize; i++)
//    {
//        ra[i] = 1;
//    }
//
//    int pre = 1, suf = 1;
//    for (int i = 1; i < numsSize; i++)
//    {
//
//        pre *= nums[i - 1];
//        suf *= nums[numsSize - i];
//        ra[i] *= pre;
//        ra[numsSize - i - 1] *= suf;
//    }
//    *returnSize = numsSize;
//    return ra;
//}




//int directions[4][2] = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} };
//
//int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize) 
//{
//    if (matrixSize == 0 || matrixColSize[0] == 0) 
//    {
//        *returnSize = 0;
//        return NULL;
//    }
//
//    int rows = matrixSize, columns = matrixColSize[0];
//    int visited[rows][columns];
//    memset(visited, 0, sizeof(visited));
//    int total = rows * columns;
//    int* order = malloc(sizeof(int) * total);
//    *returnSize = total;
//
//    int row = 0, column = 0;
//    int directionIndex = 0;
//    for (int i = 0; i < total; i++)
//    {
//        order[i] = matrix[row][column];
//        visited[row][column] = true;
//        int nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1];
//        if (nextRow < 0 || nextRow >= rows || nextColumn < 0 || nextColumn >= columns || visited[nextRow][nextColumn])
//        {
//            directionIndex = (directionIndex + 1) % 4;
//        }
//        row += directions[directionIndex][0];
//        column += directions[directionIndex][1];
//    }
//    return order;
//}



int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize)
{
    if (matrixSize == 0 || matrixColSize[0] == 0) 
    {
        *returnSize = 0;
        return NULL;
    }

    int rows = matrixSize, columns = matrixColSize[0];
    int total = rows * columns;
    int* order = malloc(sizeof(int) * total);
    *returnSize = 0;

    int left = 0, right = columns - 1, top = 0, bottom = rows - 1;
    while (left <= right && top <= bottom)
    {
        for (int column = left; column <= right; column++)
        {
            order[(*returnSize)++] = matrix[top][column];
        }
        for (int row = top + 1; row <= bottom; row++)
        {
            order[(*returnSize)++] = matrix[row][right];
        }
        if (left < right&& top < bottom) 
        {
            for (int column = right - 1; column > left; column--) 
            {
                order[(*returnSize)++] = matrix[bottom][column];
            }
            for (int row = bottom; row > top; row--) 
            {
                order[(*returnSize)++] = matrix[row][left];
            }
        }
        left++;
        right--;
        top++;
        bottom--;
    }
    return order;
}





struct hashTable
{
    int key;
    int val;
    UT_hash_handle hh;
};

int fourSumCount(int* A, int ASize, int* B, int BSize, int* C, int CSize, int* D, int DSize) 
{
    struct hashTable* hashtable = NULL;
    for (int i = 0; i < ASize; ++i) 
    {
        for (int j = 0; j < BSize; ++j) 
        {
            int ikey = A[i] + B[j];
            struct hashTable* tmp;
            HASH_FIND_INT(hashtable, &ikey, tmp);
            if (tmp == NULL) 
            {
                struct hashTable* tmp = malloc(sizeof(struct hashTable));
                tmp->key = ikey, tmp->val = 1;
                HASH_ADD_INT(hashtable, key, tmp);
            }
            else
            {
                tmp->val++;
            }
        }
    }
    int ans = 0;
    for (int i = 0; i < CSize; ++i)
    {
        for (int j = 0; j < DSize; ++j) 
        {
            int ikey = -C[i] - D[j];
            struct hashTable* tmp;
            HASH_FIND_INT(hashtable, &ikey, tmp);
            if (tmp != NULL)
            {
                ans += tmp->val;
            }
        }
    }
    return ans;
}

